#include "logmanager.h"


logmanager *logmanager::singleton = NULL;

logmanager::logmanager()
{
    DefaultPathFileInit = "preferences/config.ini";
    PathFileInit = DefaultPathFileInit;
    init();
}
logmanager::logmanager(QString path)
{

    DefaultPathFileInit = "preferences/config.ini";
    if (PathFileInit.isEmpty())
    {
        PathFileInit = DefaultPathFileInit;
    }
    else
    {
        PathFileInit = path;
    }
    init();
}
logmanager::~logmanager()
{

    SaveConfigFile(PathFileInit, "GENERAL");
    AddMessage(SUCCESS, ErrorCode + OK, __LINE__, __FILE__,
            QObject::tr("Stop desstructor"));

    do
    {
        msleep(10);
    } while (task.isRunning());

}

void logmanager::init()
{
    ErrorCode = Id_LogManager;
    LogNbLine = 0;

    // -----------------------LEVEL--------------------------
    Level = SUCCESS;
    // ------------------------------------------------------

    ReadConfigFile(PathFileInit, "GENERAL");

    //QObject::connect(this, SIGNAL(DisplayLogMessage(QString,int)), this,
    //        SLOT(DisplayMessage(QString,int)), Qt::AutoConnection); //Qt::QueuedConnection);

    ToQDebug = true;
    this->Message.Number = 0;
    PathSaveData = "";
    AddMessage(SUCCESS, 1000 + OK, __LINE__, __FILE__,"Load Logmanager");
}

/**
 *  @brief Singleton kill object
 */
void logmanager::kill()
{
    if (NULL != singleton)
    {
        delete singleton;
        singleton = NULL;
    }
}

/**
 *  @brief Singleton get current instance
 */
logmanager* logmanager::getInstance()
{
    if (NULL == singleton)
    {
        singleton = new logmanager;
    }
    else
    {
        //qDebug() <<   "Singleton already created ()" ;
    }

    return singleton;
}

/**
 *  @brief Singleton get instance first time
 */
logmanager* logmanager::getInstance(QString pathinit)
{
    if (NULL == singleton)
    {
        singleton = new logmanager(pathinit);
    }
    else
    {
        //qDebug() <<   "Singleton already created (path)" ;
    }

    return singleton;
}

/**
 *  @brief  get Phat file preference
 */
QString logmanager::GetPathFileInit()
{
    return PathFileInit;
}

/**
 *  @brief  get Phat file preference
 */
void logmanager::SetPathFileInit(QString path)
{
    if (path.isEmpty())
    {
        PathFileInit = DefaultPathFileInit;
    }
    else
    {
        PathFileInit = path;
    }
}

void logmanager::setErrorCode(int val)
{
    this->ErrorCode = val;
}

void logmanager::OpenDialLog()
{

}

/**
 *  @brief set output display to QDebug()
 */
void logmanager::setToQdebug(bool val)
{
    ToQDebug = val;
}
/**
 * @brief ThreadLogManager
 * @details this function
 * @param[in] int level of error (SUCCESS,WARNING,CRITICAL ...)
 * @param[in] int Code error (see main header documentation)
 * @param[in] int line number
 * @param[in] QString File name
 * @param[in] QString message to explain log.
 * @return int code error (SUCCESS, WARNING, ...)
 *
 */
int logmanager::ThreadAddMessage(INT32 Type, INT32 Code, UINT32 LineNumber,
        QString SourceFile, QString LogMessage)
{
    Mutex.lock();

    Message.Type = Type;
    Message.Code = Code;
    Message.LineNumber = LineNumber;
    Message.SourceFile = SourceFile;
    Message.LogMessage = LogMessage;
    Message.LocalTime.WeekDay = QDate::currentDate().day();
    Message.LocalTime.Month = QDate::currentDate().month();
    Message.LocalTime.Year = QDate::currentDate().year();
    Message.LocalTime.Hour = QTime::currentTime().hour();
    Message.LocalTime.Minute = QTime::currentTime().minute();
    Message.LocalTime.Second = QTime::currentTime().second();
    Message.LocalTime.Millisecond = QTime::currentTime().msec();
    QString etat;
    QString bgcolor;
    QString icone;
    SizeIcone = 20;
    switch (Message.Type)
    {
    case SUCCESS:
        etat = "SUCCESS";
        bgcolor = "#00ff00";
        icone = "<img src='../media/icon/ok.png' width='"
                + QString::number(SizeIcone) + "' height='"
                + QString::number(SizeIcone) + "' />";
        break;
    case WARNING:
        etat = "WARNING";
        bgcolor = "#ffff00";
        icone = "<img src='media/icon/warning.png' width='"
                + QString::number(SizeIcone) + "' height='"
                + QString::number(SizeIcone) + "' />";
        break;
    case SERIOUS:
        etat = "SERIOUS";
        bgcolor = "#ff0000";
        icone = "<img src='media/icon/RedFlag.png' width='"
                + QString::number(SizeIcone) + "' height='"
                + QString::number(SizeIcone) + "' />";
        break;
    case CRITICAL:
        etat = "CRITICAL";
        bgcolor = "#F08080";
        icone = "<img src='media/icon/error.png' width='"
                + QString::number(SizeIcone) + "' height='"
                + QString::number(SizeIcone) + "' />";
        break;
    case FATAL:
        etat = "FATAL";
        bgcolor = "#ff00ff";
        icone = "<img src='media/icon/warning2.png' width='"
                + QString::number(SizeIcone) + "' height='"
                + QString::number(SizeIcone) + "' />";
        break;
    case INFO:
        etat = "INFO";
        bgcolor = "#00ffff";
        icone = "<img src='media/icon/exclamation.png' width='"
                + QString::number(SizeIcone) + "' height='"
                + QString::number(SizeIcone) + "' />";
        break;
    default:
        etat = "NA";
        bgcolor = "#ffffff";
        icone = "<img src='media/icon/exclamation.png' width='"
                + QString::number(SizeIcone) + "' height='"
                + QString::number(SizeIcone) + "' />";
        break;
    }

    QString line;
    QString lineText;
    this->Message.Number++;
    SourceFile = SourceFile.section('\\', -1);

    if (ToQDebug)
    {
        if (!etat.compare("INFO",Qt::CaseInsensitive))
        {
            etat = "INFO\t";
        }
        if (SourceFile.size() < 8)
            SourceFile = SourceFile + "   ";
        QString line2 = QString::number(Message.Number) + "\t" + "Code:"
                + QString::number(Code) + "\t|" + etat + "\t| Line "
                + QString::number(LineNumber) + "\t" + SourceFile + "\t| > "
                + LogMessage;
        qDebug() << "|" << line2.toStdString().c_str();
    }


    line = "<table width='500px' border='0' cellspacing='0'><tr bgcolor='"
            + bgcolor + "'>" + "<td>" + icone + "</td>" + "<td width='25'>"
            + " " + QString::number(Message.Number) + "</td><td  width='70'>"
            + QString::number(Message.LocalTime.WeekDay) + ":"
            + QString::number(Message.LocalTime.Month) + ":"
            + QString::number(Message.LocalTime.Year) + "</td><td  width='80'>"
            + QString::number(Message.LocalTime.Hour) + ":"
            + QString::number(Message.LocalTime.Minute) + ":"
            + QString::number(Message.LocalTime.Second) + "-"
            + QString::number(Message.LocalTime.Millisecond)
            + "</td><td  width='65'>" + etat + "</td><td  width='35'>"
            + QString::number(this->Message.Code) + "</td><td  width='150'>"
            + SourceFile + " [" + QString::number(this->Message.LineNumber)
            + "]" + "</td><td  width='400'>" + Message.LogMessage
            + "</td></tr></table>";


    lineText = "" + QString::number(Message.Number) + " "
            + QString::number(Message.LocalTime.WeekDay) + ":"
            + QString::number(Message.LocalTime.Month) + ":"
            + QString::number(Message.LocalTime.Year) + " "
            + QString::number(Message.LocalTime.Hour) + ":"
            + QString::number(Message.LocalTime.Minute) + ":"
            + QString::number(Message.LocalTime.Second) + "-"
            + QString::number(Message.LocalTime.Millisecond) + " " + etat + " "
            + QString::number(this->Message.Code) + " "
            + this->Message.SourceFile + " ["
            + QString::number(this->Message.LineNumber) + "]" + " "
            + Message.LogMessage + "";
    //SaveFile(lineText);

    emit DisplayLogMessage(line, Message.Code);
    Mutex.unlock();
    return SUCCESS;
}

/**
 * @brief Mise en forme de la ligne de log
 * @param[in] Type (WARNING,SUCCESS,CRITICAL...
 * @param[in] Code Code erreur de la camera, monture Etc...
 * @param[in] LineNumber Numero de la ligne
 * @param[in] SourceFile fichier
 * @param[in] LogMessage Commentaire du log
 * @return Status SUCCESS, CRITICAL ...
 */
int logmanager::AddMessage(INT32 Type, INT32 Code, UINT32 LineNumber,
        QString SourceFile, QString LogMessage)
{
    if (Type >= Level)
    {
        task = QtConcurrent::run(this, &logmanager::ThreadAddMessage, Type,
                Code, LineNumber, SourceFile, LogMessage);

    }
    return SUCCESS;
}

/**
 * @brief Set level
 * @param[in] int level (SUCCESS, WARNING, CRITICAL)
 */
void logmanager::setLevel(int lev)
{
//	if (lev >  0 )
//		lev = -lev;
    Level = lev;
}
/**
 * @brief get Level
 * @return Status SUCCESS, CRITICAL ...
 */
int logmanager::getLevel()
{
    return Level;
}

/**
 * @brief Mise en forme de la ligne de log
 * @param[in] Log ligne de log
 * @param[in] Path Chemin et nom du fichier de log
 * @return Status SUCCESS, CRITICAL ...
 */
int logmanager::SaveFile(QString logligne)
{
    QString FileName;
    QString DateFolder;
    QString PathLog;
    QString ligne;
    QDate DateUTC;
    QDir directory;
    QFile FileLog;

    DateUTC = QDateTime::currentDateTime().toUTC().date();
    FileName = "DIMM_Log_" + DateUTC.toString("yyyy.MM.dd") + ".txt";
    DateFolder = "DIMM_" + DateUTC.toString("yyyy-MM-dd");
    if (directory.exists(this->getPathSaveData()))
    {
        if (!directory.exists(this->getPathSaveData() + "//" + DateFolder))
        {
            // Creation automatique du repertoire
            if (directory.mkdir(this->getPathSaveData() + "//" + DateFolder)
                    == true)
            {
                //this->AddMessage(INFO,0,__LINE__,__FILE__,"Creation d'un nouveau repertoire" + this->getPathSaveData() + "/" + DateFolder);
                //qDebug() << "Creation d'un nouveau repertoire pour le log";
            }
            else
            {
                //this->AddMessage(WARNING,0,__LINE__,__FILE__,"Impossible de creer le repertoire" + this->getPathSaveData() + "/" + DateFolder);
                //qDebug() << "Impossible de creer le repertoire pour le log";
            }
        }
    }
    PathLog = this->getPathSaveData() + "//" + DateFolder + "//" + FileName;
    FileLog.setFileName(PathLog);
    QTextStream flux(&FileLog);

    if (!FileLog.exists())
    {
        //qDebug() << "Creation d'un fichier log: ";
    }
    else
    {

    }
    FileLog.open(QIODevice::WriteOnly | QIODevice::Append);
    flux << logligne << endl;
    FileLog.close();

    return SUCCESS;
}

/**
 * @brief Read configuration file
 * @details all windows position are saved
 * flag Show of dialog preference is saved.
 *
 * @param[in] QString path of file (ie. preferences/config.ini)
 * @param[in] QString key for file init (ie. GENRAL)
 */
int logmanager::ReadConfigFile(QString path, QString key)
{

    QFile file(QDir::toNativeSeparators(path));
    if (!file.exists())
    {
        return WARNING;
    };
    QSettings settings(path, QSettings::IniFormat);
    QString MsgError = "(" + QObject::tr("read") + "):"
            + QObject::tr("Key no present, initialized to") + ": ";

    // Search general parameter
    settings.beginGroup(key);
    /*
    if (pWinLog)
    {
        pWinLog->restoreGeometry(
                settings.value("WinLog/Geometry").toByteArray());
        pWinLog->updateGeometry();
        if (settings.value("WinLog/Show", false).toBool())
        {
            pWinLog->show();
            pWinLog->activateWindow();
        }
    }
    */
    setLevel(settings.value("Log_Level", SUCCESS).toInt());

    settings.endGroup();
    return SUCCESS;
}

/**
 * @brief Save configuration file
 * @details all windows position are restored
 * Window pref is display at prior state
 *
 * @param[in] QString path of file (ie. preferences/config.ini)
 * @param[in] QString key for file init (ie. GENRAL)
 */
int logmanager::SaveConfigFile(QString path, QString key)
{
    QFile file(QDir::toNativeSeparators(path));
    if (!file.exists())
    {
        AddMessage(WARNING, ErrorCode + NOFILE, __LINE__, __FILE__,
                QObject::tr("Warning no configuration file") + ": " + path);
        return WARNING;
    };
    QSettings settings(path, QSettings::IniFormat);

    // write  parameters
    settings.beginGroup(key);
    //settings.setValue("WinLog/Geometry", pWinLog->saveGeometry());
    //settings.setValue("WinLog/Show", pWinLog->isVisible());
    settings.setValue("Log_Level", getLevel());
    settings.endGroup();

    return SUCCESS;
}

void logmanager::DisplayMessage(QString /*line*/, int /*code*/)
{
/*
    LogNbLine++;
    QTextCursor tc = pWinLog->TextLog->textCursor();
    if (LogNbLine > 200)
    {
        pWinLog->TextLog->clear();
        LogNbLine = 0;


         //tc.movePosition( QTextCursor::Start );
         //tc.select( QTextCursor::LineUnderCursor );
         //tc.removeSelectedText();


    }
    pWinLog->TextLog->insertHtml(line);
    pWinLog->TextLog->ensureCursorVisible();
//	pWinLog->TextLog->moveCursor(QTextCursor::End);
    tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
*/

}
